﻿using AutoMapper;
using BW.MesProject.Equipment.Domain.Enum;
using BW.MesProject.Equipment.Domain.Equipment;
using BW.MesProject.Equipment.Domain.Extensions;
using BW.MesProject.Equipment.Infrastructure.Dto.Input;
using BW.MesProject.Equipment.Infrastructure.Dto.Input.ProjectMaintenance;
using BW.MesProject.Equipment.Infrastructure.Dto.Output.ProjectMaintenance;
using BW.MesProject.Equipment.Infrastructure.Equipment;
using BW.MesProject.Public.ErrorCode;
using BW.MesProject.Public.Infrastructure;
using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks; 
using Yitter.IdGenerator;
using Microsoft.AspNetCore.Http;
using SqlSugar;

namespace BW.MesProject.Equipment.Application.Equipment
{
    /// <summary>
    /// 项目维护服务实现层
    /// </summary>
    public class ProjectMaintenanceService : IProjectMaintenanceService
    {
        private readonly IBaseRepository<ProjectMaintenanceModel> _projectMainRepository;
        private readonly IMapper _mapper;
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly ISqlSugarClient _sqlSugarClient;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="ProjectMainRepository"></param>
        /// <param name="mapper"></param>
        public ProjectMaintenanceService(IBaseRepository<ProjectMaintenanceModel> ProjectMainRepository,IMapper mapper, IHttpContextAccessor httpContextAccessor,ISqlSugarClient sqlSugarClient)
        {
            _projectMainRepository = ProjectMainRepository;
            this._mapper = mapper;
            this._httpContextAccessor = httpContextAccessor;
            this._sqlSugarClient = sqlSugarClient;
        }

        /// <summary>
        /// 添加项目维护
        /// </summary>
        /// <param name="input">添加项目维护输入参数</param>
        /// <returns>返回操作结果，包含状态码、提示信息及受影响的行数</returns>
        public ApiResult<int> AddProjectMaintenance(AddProjectMaintenanceInput input)
        {
            try
            {
                // 使用正确的事务处理方式
                var result = new ApiResult<int>();

                // 获取一个可用的DbContext
                var db = _sqlSugarClient as SqlSugarScope; // 尝试转换为SqlSugarScope
                if (db == null)
                {
                    // 如果不是SqlSugarScope，尝试获取SimpleClient
                    var repository = _projectMainRepository as SimpleClient<ProjectMaintenanceModel>;
                    if (repository != null)
                    {
                        db = repository.Context as SqlSugarScope;
                    }
                }

                if (db != null)
                {
                    // 使用SqlSugarScope的事务方法
                    db.BeginTran();

                    try
                    {
                        // 使用AutoMapper将输入参数映射为实体对象
                        var data = _mapper.Map<ProjectMaintenanceModel>(input);

                        // 生成项目维护编码：PM+当前日期（yyyyMMdd）+4位随机数
                        var newCode = "PM" + DateTime.Now.ToString("yyyyMMdd") + new Random().Next(1000, 9999);
                        data.ProjectMaintenanceCode = newCode;

                        // 生成唯一主键Id
                        data.Id = YitIdHelper.NextId();

                        // 判断项目维护名称是否已存在，避免重复
                        var isExist = _projectMainRepository.GetValue(x => x.ProjectMaintenanceName == data.ProjectMaintenanceName);
                        if (isExist != null)
                        {
                            // 如果已存在，返回错误信息
                            db.RollbackTran();
                            return new ApiResult<int>
                            {
                                Code = ApiEnums.Error,
                                Message = "项目维护名称已存在"
                            };
                        }

                        // 获取当前登录用户名并设置为创建人
                        var userName = _httpContextAccessor.HttpContext?.User?.Identity?.Name;
                        data.CreatedBy = userName ?? "system"; // 如果无法获取用户名，则设置为"system"
                        data.CreatedTime = DateTime.Now; // 同时设置创建时间

                        // 添加项目维护数据到数据库
                        var res = _projectMainRepository.Add(data);

                        // 提交事务
                        db.CommitTran();

                        // 返回成功结果
                        result.Code = ApiEnums.Success;
                        result.Message = "添加成功";
                        result.Data = res;
                    }
                    catch (Exception ex)
                    {
                        // 发生异常时回滚事务
                        db.RollbackTran();
                        throw; // 重新抛出异常，让外部try-catch捕获
                    }
                }
                else
                {
                    // 如果无法获取事务对象，则使用普通方式执行
                    // 使用AutoMapper将输入参数映射为实体对象
                    var data = _mapper.Map<ProjectMaintenanceModel>(input);

                    // 生成项目维护编码：PM+当前日期（yyyyMMdd）+4位随机数
                    var newCode = "PM" + DateTime.Now.ToString("yyyyMMdd") + new Random().Next(1000, 9999);
                    data.ProjectMaintenanceCode = newCode;

                    // 生成唯一主键Id
                    data.Id = YitIdHelper.NextId();

                    // 判断项目维护名称是否已存在，避免重复
                    var isExist = _projectMainRepository.GetValue(x => x.ProjectMaintenanceName == data.ProjectMaintenanceName);
                    if (isExist != null)
                    {
                        // 如果已存在，返回错误信息
                        return new ApiResult<int>
                        {
                            Code = ApiEnums.Error,
                            Message = "项目维护名称已存在"
                        };
                    }

                    // 获取当前登录用户名并设置为创建人
                    var userName = _httpContextAccessor.HttpContext?.User?.Identity?.Name;
                    data.CreatedBy = userName ?? "system"; // 如果无法获取用户名，则设置为"system"
                    data.CreatedTime = DateTime.Now; // 同时设置创建时间

                    // 添加项目维护数据到数据库
                    var res = _projectMainRepository.Add(data);

                    // 返回成功结果
                    result.Code = ApiEnums.Success;
                    result.Message = "添加成功";
                    result.Data = res;
                }

                return result;
            }
            catch (Exception ex)
            {
                return new ApiResult<int>
                {
                    Code = ApiEnums.Error,
                    Message = $"添加失败: {ex.Message}",
                    Data = 0
                };
            }
        }

        /// <summary>
        /// 项目维护显示列表
        /// </summary>
        /// <param name="input">项目维护查询输入参数</param>
        /// <returns>返回分页后的项目维护输出列表</returns>
        public ApiPaging<ProjectMaintenanceOutput> GetProjectMaintenanceList(ProjectMaintenanceQueryInput input)
        {
            // 获取未被逻辑删除的项目维护数据
            var projectMaintenanceList = _projectMainRepository.GetAll().Where(x => !x.IsDeleted);

            // 如果输入了项目维护编码，则按编码精确筛选
            if (!string.IsNullOrEmpty(input.ProjectMaintenanceCode))
            {
                projectMaintenanceList = projectMaintenanceList.Where(x => x.ProjectMaintenanceCode == input.ProjectMaintenanceCode);
            }
            // 如果输入了项目维护名称，则按名称模糊筛选
            if (!string.IsNullOrEmpty(input.ProjectMaintenanceName))
            {
                projectMaintenanceList = projectMaintenanceList.Where(x => x.ProjectMaintenanceName.Contains(input.ProjectMaintenanceName));
            }
            // 如果输入了判定基准，则按基准模糊筛选
            if (!string.IsNullOrEmpty(input.Criterion))
            {
                projectMaintenanceList = projectMaintenanceList.Where(x => x.Criterion.Contains(input.Criterion));
            }

            // 按Id倒序排序，并进行分页（跳过前面页的数据，取当前页的数据）
            var pageData = projectMaintenanceList
                .OrderByDescending(x => x.Id)
                .Skip((input.PageIndex - 1) * input.PageSize)
                .Take(input.PageSize)
                .ToList();

            // 使用AutoMapper将实体对象列表映射为输出DTO列表
            var data = _mapper.Map<List<ProjectMaintenanceOutput>>(pageData);

            // 为每个项目添加检验方式文本描述
            foreach (var item in data)
            {
                // 将int转为枚举再获取描述
                if (Enum.IsDefined(typeof(CheckoutWayEnum), item.CheckoutWay))
                {
                    var checkoutWay = (CheckoutWayEnum)item.CheckoutWay;
                    
                    // 使用扩展方法获取描述
                    item.CheckoutWayText = checkoutWay.GetDescription(); 
                }
                else
                {
                    item.CheckoutWayText = "未知方式";
                }
            }
            // 返回分页结果，包括数据、总条数、状态码和提示信息
            return new ApiPaging<ProjectMaintenanceOutput>
            {
                Code = ApiEnums.Success,
                Message = "项目维护获取成功",
                PageData = data,
                TotalCount = projectMaintenanceList.Count(), // 注意：此处应为筛选后的总条数
            };
        }


        /// <summary>
        /// 逻辑删除项目维护数据
        /// </summary>
        /// <param name="id">项目维护ID</param>
        /// <returns>返回操作结果，包含状态码、提示信息及受影响的行数</returns>
        public ApiResult<int> DeleteProjectMaintenance(long id)
        {
            // 根据ID获取项目维护实体
            var projectMaintenance = _projectMainRepository.GetValue(x => x.Id == id);
            if (projectMaintenance == null)
            {
                // 未找到对应数据，返回失败
                return new ApiResult<int>
                {
                    Code = ApiEnums.Fail,
                    Message = "项目维护不存在",
                    Data = 0
                };
            }
            // 设置逻辑删除标志
            projectMaintenance.IsDeleted = true;
            // 更新数据库
            var res = _projectMainRepository.Update(projectMaintenance);
            // 返回成功结果
            return new ApiResult<int>
            {
                Code = ApiEnums.Success,
                Message = "项目维护删除成功",
                Data = res
            };
        }


        /// <summary>
        /// 根据项目维护ID查询项目维护数据
        /// </summary>
        /// <param name="id">项目维护ID</param>
        /// <returns>返回操作结果，包含状态码、提示信息及项目维护输出数据</returns>
        public ApiResult<ProjectMaintenanceOutput> GetProjectMaintenanceValue(long id)
        {
            // 根据ID获取项目维护实体
            var res = _projectMainRepository.GetValue(x => x.Id == id);
            // 返回查询结果，若未找到则Data为null
            return new ApiResult<ProjectMaintenanceOutput>
            {
                Code = res != null ? ApiEnums.Success : ApiEnums.Fail,
                Message = res != null ? "查询成功" : "查询失败",
                Data = _mapper.Map<ProjectMaintenanceOutput>(res)
            };
        }

        /// <summary>
        /// 修改项目维护
        /// </summary>
        /// <param name="input">修改项目维护输入参数</param>
        /// <returns>返回操作结果，包含状态码、提示信息及受影响的行数</returns>
        public ApiResult<int> UpdateProjectMaintenance(UpdateProjectMaintenanceInput input)
        {
            // 根据ID获取项目维护实体
            var projectMaintenanceModel = _projectMainRepository.GetValue(x => x.Id == input.Id);
            // 判断是否存在
            if (projectMaintenanceModel == null)
            {
                return new ApiResult<int>
                {
                    Code = ApiEnums.Fail,
                    Message = "您要修改的项目维护不存在",
                    Data = 0
                };
            }
            // 使用AutoMapper将输入参数映射到已有实体对象
            projectMaintenanceModel = _mapper.Map(input, projectMaintenanceModel);
            // 更新时间为当前时间
            projectMaintenanceModel.UpdatedTime = DateTime.Now;

            // 判断项目维护名称是否已存在（排除自身）
            var projectMaintenanceName = _projectMainRepository.GetValue(x => x.ProjectMaintenanceName == input.ProjectMaintenanceName && x.Id != input.Id);
            if (projectMaintenanceName != null)
            {
                return new ApiResult<int>
                {
                    Code = ApiEnums.Fail,
                    Message = "项目维护名称已存在",
                    Data = 0
                };
            }

            // 更新数据库
            var res = _projectMainRepository.Update(projectMaintenanceModel);

            // 返回成功结果
            return new ApiResult<int>
            {
                Code = ApiEnums.Success,
                Message = "修改成功",
                Data = res
            };
        }
    }
}
